package org.web.locks.databasedistributedlocks.sdk.dto;

import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.StringUtils;
import org.web.base.domain.DeleteGroup;
import org.web.base.domain.InsertGroup;
import org.web.locks.databasedistributedlocks.sdk.helper.ProcessIdentifierHelper;

import javax.validation.constraints.*;
import java.io.Serializable;
import java.util.UUID;

@Setter
@Getter
public class LockDTO implements Serializable {

    private static final long serialVersionUID = 1L;


    public LockDTO(@NotEmpty(message = "锁标记不能为空") String distributedLocksId, Integer lockExpiryTime) {
        this(distributedLocksId, lockExpiryTime, null);
    }

    public LockDTO(@NotEmpty(message = "锁标记不能为空") String distributedLocksId, Integer lockExpiryTime, String lockOwner) {
        this.distributedLocksId = distributedLocksId;
        if (StringUtils.isEmpty(lockOwner)) {
            this.lockOwner = ProcessIdentifierHelper.getProcessIdentifier() + "@" + UUID.randomUUID();
        } else {
            this.lockOwner = lockOwner;
        }
        this.lockExpiryTime = lockExpiryTime;
    }

    /**
     * 业务标识，使用方提供，同时也是分布式锁表的主键，创建时，必须指定，由业务接入方提供。
     */
    @NotBlank(message = "创建时，distributedLocksId 必须指定. ", groups = {InsertGroup.class, DeleteGroup.class})
    @Size(max = 100, message = "distributedLocksId 长度不能超过{100}个字符. ", groups = {InsertGroup.class, DeleteGroup.class})
    private String distributedLocksId;

    /**
     * 过期时间，单位毫秒，@Max(value = 300000,message = 最大值为5分钟}。 , groups = {InsertGroup.class, DeleteGroup.class})，@Min(value = 500,message = 最小值为500毫秒}。 , groups = {InsertGroup.class, DeleteGroup.class})
     */
    @Max(value = 300000, groups = {InsertGroup.class})
    @Min(value = 0, groups = {InsertGroup.class})
    private Integer lockExpiryTime;

    /**
     * 拥有者，标记锁的拥有者，有两部分构成，固定部分和输入部分。
     * 固定部分：标注的是当前进程的标识，格式为：host@pid@uuid，其中host为主机名，pid为进程号，uuid为随机生成的UUID,用于标识当前进程。
     * 输入部分：来源有两个场景， 一个是默认提供的，即随机生成的UUID，默认实现，是保证唯一性的。
     * 另一个是用户输入的，由用户指定，其唯一性由用户保证。
     * lockOwner 作用，一是标识当前锁的拥有者，二是判断锁的拥有者，可以进行重入，不断尝试获取锁，以及更新锁的过期时间。
     */
    @NotBlank(message = "创建时，lockOwner 必须指定. ", groups = {InsertGroup.class})
    @Size(max = 255, message = "lockOwner 长度不能超过{255}个字符. ", groups = {InsertGroup.class, DeleteGroup.class})
    private String lockOwner;


}
